#ifndef VertexElementColor_h
#define VertexElementColor_h

#include <Defines.h>
#include <CSharpPropertyMethods.h>

// Riccsson includes.
#include <System/Object.h>
#include <System/Type.h>
#include <System/String.h>

// XNA includes.
#include "../../Color.h"

namespace Riccsson
{
	namespace Xna
	{
		namespace Framework
		{
			namespace Graphics
			{
	            struct VertexElementColor
					: public Riccsson::System::Object
	            {
		            byte R;
		            byte G;
		            byte B;
		            byte A;
					
					PROP3(VertexElementColor, uint, PackedValue)
					PROP3(VertexElementColor, Color, color)
					
					COPY_CONSTRUCTOR(VertexElementColor)
					{
						PROP3_INIT_COPY(VertexElementColor, uint, PackedValue);
						PROP3_INIT_COPY(VertexElementColor, Color, color);

						R = other.A;
			            G = other.G;
			            B = other.B;
			            A = other.A;
					}

					public: VertexElementColor ()
						: PROP3_INIT(VertexElementColor, PackedValue)
						, PROP3_INIT(VertexElementColor, color)
		            {
			            R = 255;
			            G = 255;
			            B = 255;
			            A = 255;
		            }

		            public: VertexElementColor (Color color)
						: PROP3_INIT(VertexElementColor, PackedValue)
						, PROP3_INIT(VertexElementColor, color)
		            {
			            R = color.R;
			            G = color.G;
			            B = color.B;
			            A = color.A;
		            }

		            public: PROP3_GET(Color, color)
					{
				        return Color (R, G, B, A);
			        }
			        public: PROP3_SET(Color, color)
					{
				        R = value.R;
				        G = value.G;
				        B = value.B;
				        A = value.A;
		            }

                    public: PROP3_GET(uint, PackedValue)
					{
                        // ARGB
                        uint _packedValue = 0;
                        _packedValue = (_packedValue & 0xffffff00) | R;
                        _packedValue = (_packedValue & 0xffff00ff) | ((uint)(G << 8));
                        _packedValue = (_packedValue & 0xff00ffff) | ((uint)(B << 16));
                        _packedValue = (_packedValue & 0x00ffffff) | ((uint)(A << 24));
                        return _packedValue;
                    }
                    public: PROP3_SET(uint, PackedValue)
					{
                        R = (byte)value;
                        G = (byte)(value >> 8);
                        B = (byte)(value >> 16);
                        A = (byte)(value >> 24);
                    }

		            public: override GC_PTR<Riccsson::System::string> ToString ()
		            {
			            //return string.Format ("[Color: R={0}, G={1}, B={2}, A={3}]", R, G, B, A);
						throw;
		            }

					public: override bool Equals (Riccsson::System::object* obj)
		            {
			            if (obj == null) {
				            return false;
			            }
			            if (obj->GetType () != Riccsson::System::object::GetType ()) {
				            return false;
			            }
			            return (this == ((VertexElementColor*)obj));
		            }

                    public: override int GetHashCode()
                    {
                        return (int)PackedValue;
                    }

					/*implicit*/  Color operator=(VertexElementColor& typ)
					{
						// code to convert from  Color to VertexElementColor
						// and return a Color object.
						Color c = Color ();
						c.R = typ.R;
						c.G = typ.G;
						c.B = typ.B;
						c.A = typ.A;
						return c;
					}
	            };

				
				// TOIO: Must be a member function.
		        ///*implicit*/ VertexElementColor operator=(Color& typ)
		        //{
			    //    // code to convert from  VertextElementColor to Color
			    //    // and return a VertexElementColor object.
			    //    VertexElementColor c = VertexElementColor (typ);
			    //    return c;
		        //}

		        bool operator == (VertexElementColor& left, Color& right)
		        {
			        return ( left.R == right.R && left.G == right.G && left.B == right.B && left.A == right.A);
		        }

		        bool operator != (VertexElementColor& left, Color& right)
		        {
			        return !(left == right);
		        }

            }
		}
	}
}

#endif

